package ch.uzh.ifi.seal.ssqa.importer.versioncontrol;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import net.sourceforge.clearcase.commandline.CleartoolCommandLine;

import org.eclipse.jface.preference.IPreferenceStore;

import ch.uzh.ifi.seal.ssqa.SsqaPlugin;
import ch.uzh.ifi.seal.ssqa.model.ChangeSet;
import ch.uzh.ifi.seal.ssqa.model.DiffReport;
import ch.uzh.ifi.seal.ssqa.model.ModelFactory;
import ch.uzh.ifi.seal.ssqa.model.Revision;
import ch.uzh.ifi.seal.ssqa.model.UcmActivity;
import ch.uzh.ifi.seal.ssqa.preferences.PreferenceConstants;
import ch.uzh.ifi.seal.ssqa.storage.IStorage;
import ch.uzh.ifi.seal.ssqa.storage.StorageResult;
import ch.uzh.ifi.seal.ssqa.storage.TeneoHibernateStorage;

public class ClearCaseImporter{

	public static final String SEG = "#PROPERTY#";
	int count = 0;

	private void mountVOBs() {
		new ClearCaseVOBMounter().mountConfiguredVobs();
	}
	
	public void persistData() {
		this.mountVOBs();
		this.persistActivities();
		IPreferenceStore store = SsqaPlugin.getDefault().getPreferenceStore();
		if(store.getBoolean(PreferenceConstants.CC_DIFF_REPORTS)){
			this.readOutDiffReports();
		}
	}
	
	private void persistActivities(){
		ArrayList<UcmActivity> activities = new ArrayList<UcmActivity>();

		CleartoolCommandLine ct = new CleartoolCommandLine("lsact");

		String format = "-fmt";
		ct.addOption(format);
		ct.addElement("\" %n " + ClearCaseImporter.SEG +" %[stream]Xp "+ ClearCaseImporter.SEG + " %[versions]CQp " + ClearCaseImporter.SEG + " %[headline]p \n \"");
		ct.addElement("-invob");
		ct.addElement("UCM_PVOB_PF91");
		//ct.addElement("PF9100172141");
		System.out.println("#### Start ClearCase Import ##########################################");
		System.out.println(Arrays.toString(ct.create()));		
		String[] output = null;
		String[] errorOutput = null;
		try {
			Map<String,String[]> cmdResult = new ClearCaseCommand(ct).execute();
			output = cmdResult.get(ClearCaseCommand.SUCCEED);
			errorOutput = cmdResult.get(ClearCaseCommand.FAIL);
		} catch (Exception e){
			e.printStackTrace();
		}
		if(errorOutput != null && errorOutput.length != 0){
			System.out.println("### Clear Case command executes and returns the following Errors:");
			for(String line: errorOutput){
				System.out.println(line);
			}
		}
		if(output != null){
			for (String activity : output) {
				if (activity != null  &&  !activity.trim().equals("")) {
					count++;
					UcmActivity activityObject = this.createActivity(activity);
					if(activityObject != null){
						activities.add(activityObject);
						System.out.println("File: " + count);
					}
				}
			}
		}
		if(activities.size() > 0){
			IStorage storage = new TeneoHibernateStorage();
			storage.saveOrUpdateEntity(activities);
		}
		System.out.println("#### End ClearCase Import ##########################################");
	}

	private UcmActivity createActivity(String activityString) {
		String[] activityProperties = activityString.split(ClearCaseImporter.SEG);
		UcmActivity activity = ModelFactory.eINSTANCE.createUcmActivity();
		String identifier = activityProperties[0].trim();
		String headline = activityProperties[3].trim();
		
		if(headline != null && headline != ""){
			activity.setHeadline(headline);
		}
		
		if(identifier != null && identifier != "" && identifier.startsWith("PF91")){
			activity.setIdentifier(identifier);
			String stream = activityProperties[1].trim();
			String versions = activityProperties[2].trim();
			
			
			if(stream != null && stream != ""){
				for (String file : versions.split("\", \"")) {
					
					file = this.trimString(file, "\"");
					
					//TODO: Has to be done configurable
					if(file.contains("CCFS\\src")){
						Revision revision = ModelFactory.eINSTANCE.createRevision();
						
						revision.setStream(this.trimString(stream, "stream:"));
						
						String[] fileParts = file.split("@@");
						if(fileParts[0] != null &&fileParts[0].trim() != ""){
							//TODO: Has to be done configurable
							revision.setFilePath(this.trimString(fileParts[0], "CCFS\\src").replace("\\", "/"));
						}
						
						revision.setRevisionFilePath(file);
						
						String revisionString = file.substring(file.lastIndexOf("\\") + 1);
						if (revisionString != null && revisionString != ""){
							int revisionNumber = this.parseInt(revisionString);
							if(revisionNumber != -1){
								revision.setRevisionNumber(Integer.parseInt(file.substring(file.lastIndexOf("\\") + 1)));
							}
						}
						revision.setUcmActivity(activity);
						activity.getFileRevisons().add(revision);
					}
				}
			}
			return activity;
		} else {
			System.out.println("Return NULL");
			return null;
		}
	}
	
	private int parseInt(String intString){
		try{
			return Integer.parseInt(intString);
		}catch (Exception e  ){
			return -1;
		}
	}

	public void readOutDiffReports(){
		IStorage storage = new TeneoHibernateStorage();
		StorageResult result = storage.executeUniqueQuery("from Revision");
		List<Revision> revisions = (List<Revision>)result.getListResult();
		for(Revision revision : revisions){
			if(revision.getDiffReport().equals(null)){
				DiffReport report = this.getDiffReport(revision.getRevisionFilePath());
				if(report != null){
					revision.setDiffReport(report);
				}
			}
		}
		result.getSession().getTransaction().commit();
		result.getSession().close();
	}
	
	private DiffReport getDiffReport(String file) {
		CleartoolCommandLine ct = new CleartoolCommandLine("diff");
		ct.addOption("-serial_format");
		ct.addOption("-predecessor");
		ct.addElement(file);
		DiffReport report = ModelFactory.eINSTANCE.createDiffReport();
		ChangeSet changeSet = null;
		
		Map<String,String[]> cmdResult = new ClearCaseCommand(ct).execute();
		
		try{
			for(String line: cmdResult.get(ClearCaseCommand.SUCCEED)){
				if (line.startsWith("<<< file 1:")) {
					report.setFirstFile(line.replace("<<< file 1:", "").trim());
				} else if (line.startsWith(">>> file 2:")) {
					report.setSecondFile(line.replace(">>> file 2:", "").trim());
				} else if (line.startsWith("-----[") && line.endsWith("]-----")) {
					if (changeSet != null) {
						ChangeSet oldChangeSet = changeSet;
						report.getChangeSets().add(oldChangeSet);
					}
					changeSet = ModelFactory.eINSTANCE.createChangeSet();
					changeSet.setIntervalDefinition(line.replace("-----[", "")
							.replace("]-----", "").trim());
				} else {
					if (line.startsWith(">")) {
						changeSet.getAddedLines().add(line.replace(">", ""));
					} else if (line.startsWith("<")) {
						System.out.println(line);
						changeSet.getDeletedLines().add(line.replace("<", ""));
					}
				}
			}
			if(cmdResult.get(ClearCaseCommand.FAIL).length != 0){
				System.out.println("### Clear Case command executes and returns the following Errors:");
				for(String line: cmdResult.get(ClearCaseCommand.FAIL)){
					System.out.println(line);
				}
			}			
				
		}catch(Exception e){
			e.printStackTrace();
		}
		return report;
	}

	private String trimString(String string, String trimmer) {
		string = string.trim();
		string = string.startsWith(trimmer) ? string.substring(1,
				string.length()) : string;
		string = string.endsWith(trimmer) ? string.substring(0,
				string.length() - 1) : string;
		return string;
	}
}
